package com.ht.api.bigtask.impl.official;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.ht.api.bigtask.BaseBigTask;
import com.ht.api.db.Db;
import com.ht.api.db.DbList;
import com.ht.api.db.Entity;
import com.ht.api.open.OpenUtil;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 微信公众号初始化任务：查询用户列表
 * @author asq
 * @createTime 2025年4月10日 17:29:04
 */
@Slf4j
public class QueryUserListTask extends BaseBigTask {
	/** 接口:获取用户列表 */
	private static final long API_ID_USER_LIST = 1899458961271296000L;
	/** 接口:获取用户基本信息 */
	private static final long API_ID_USER_INFO = 1909548820774129664L;

	@Override
	protected void doExecute(String appId, JSONObject context, Entity bean) {
	    long time = System.currentTimeMillis();
	    
		// 获取用户列表
		String str = OpenUtil.call(appId, API_ID_USER_LIST, JSONUtil.createObj());
		JSONObject entity = JSONUtil.parseObj(str);
		
		// 用多线程并发获取用户详情
		ExecutorService executor = Executors.newFixedThreadPool(50);
		
		// 循环获取用户详情
		JSONObject date = entity.getJSONObject("data");
		JSONArray openids = date.getJSONArray("openid");
		CountDownLatch latch = new CountDownLatch(openids.size());
		DbList list = DbList.create();
		for (int i = 0; i < openids.size(); i++) {
			String openid = openids.getStr(i);
			
			// 多线程并发拉取用户详情
			executor.submit(() -> {
				try {
					String strInfo = OpenUtil.call(appId, API_ID_USER_INFO, JSONUtil.createObj().set("openid", openid));
					Entity openData = createOpenDataEntity(appId, API_ID_USER_INFO, JSONUtil.parseObj(strInfo));
					list.add(openData);
				} catch (Exception e) {
					log.error("[QueryProductListTask] 拉取用户详情发生异常：{}", e.getMessage(), e);
				} finally {
					latch.countDown(); 
				}
			});
		}
		
		// 所有任务完成后继续
		try {
            latch.await();
            Db.insertBatchWithStream(getTenantStreamConfig(appId), list);
            log.info("[QueryProductListTask] 全部任务完成，用户数：{}，耗时：{}ms", list.size(), (System.currentTimeMillis() - time));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // 恢复中断状态
            log.error("等待并发获取用户详情任务完成时被中断", e);
        }
	}

}
